package com.szeldon.declatest.runners;

import java.io.File;
import java.io.IOException;

import javax.jms.JMSException;
import javax.naming.NamingException;

import org.apache.activemq.broker.BrokerService;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;

import com.szeldon.utils.FileUtils;

/**
 * Tester for whole functionality of Declatest. Runners, executors and etc. aren't tested here. This place justs tests
 * if there weren't any errors in Main class and if reports are what there were suppose to be. So there's an input and
 * expected output of the running of Declatest as a whole program.
 * 
 * @author szeldon
 * 
 */
public class MainTest {

    private static final String RESOURCE_FOLDER = "tests-res/com/szeldon/declatest/runners/";
    private static final String OUTPUT_FOLDER = "output/reports/";

    @BeforeClass
    public void beforeClass(ITestContext context) throws Exception {
        BrokerService brokerService = (BrokerService) context
                .getAttribute(MainTestConfigurator.CONTEXT_ATTRIBUTE_NAME_FOR_JMS_SERVER);
        brokerService.getAdminView().addQueue("response_queue_name");
    }

    @Test
    public void testBasicMainWithSendReceiveJms() throws IOException, SAXException, JMSException, NamingException,
            InterruptedException {

        MainTestMessageListener listener = new MainTestMessageListener("tcp://localhost:61616", "queue_name",
                "dynamicQueues/response_queue_name", null, FileUtils.readFileContent(RESOURCE_FOLDER
                        + "declaration01-response01.xml"));
        listener.start();

        String xmlDeclarationFileName = RESOURCE_FOLDER + "declaration01.xml", xmlReportsFolderName = OUTPUT_FOLDER
                + "reports/xml/", pluginsReportsFolderName = OUTPUT_FOLDER + "reports/plugins/";
        String[] args = new String[] { "-s", xmlDeclarationFileName, "-d", xmlReportsFolderName, "-p",
                pluginsReportsFolderName };
        Main main = new Main(args);
        main.start();

        // checks if there's a report in XML and HTML
        File xmlReportFile = checkIfExists(xmlReportsFolderName, "\\d{8}-\\d{6}.xml");
        File htmlReportFile = checkIfExists(pluginsReportsFolderName + "html/", "report-\\d{8}-\\d{6}.html");

        while (!listener.isTestEnded()) {
            Thread.sleep(200);
        }

        Assert.assertEquals(listener.isTestPassed(), true);

        // TODO: parse html and check if it contains expected data

        // cleans after itself
        xmlReportFile.delete();
        htmlReportFile.delete();

    }

    /**
     * 
     * @param folderName
     * @param fileNameRegex
     * @return Returns file that was checked for existence.
     */
    private File checkIfExists(String folderName, String fileNameRegex) {
        File folder = new File(folderName);
        Assert.assertEquals(folder.exists(), true, "Expecting " + folder.getPath() + " to exist.");
        Assert.assertEquals(folder.isDirectory(), true);
        File[] filesInFolder = folder.listFiles();
        Assert.assertEquals(filesInFolder.length, 1);
        File file = filesInFolder[0];
        Assert.assertEquals(file.getName().matches(fileNameRegex), true, "Expecting " + file.getName()
                + " to match regex '" + fileNameRegex + "'.");

        return file;
    }

}
